import sys
import os
import logging
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
                             QHBoxLayout, QLabel, QPushButton, QFileDialog,
                             QMessageBox, QProgressBar, QFrame, QGroupBox, QSizePolicy)
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtGui import QFont, QIcon, QPixmap, QColor
from pdf2docx import parse

# 配置日志系统
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.StreamHandler(),
        logging.FileHandler('pdf_converter.log')
    ]
)


class PDFConverterThread(QThread):
    """PDF转换线程"""
    progress_updated = pyqtSignal(int, str)
    conversion_finished = pyqtSignal(bool, str)

    def __init__(self, pdf_path, docx_path):
        super().__init__()
        self.pdf_path = pdf_path
        self.docx_path = docx_path
        self._cancel = False

    def run(self):
        try:
            parse(
                self.pdf_path,
                self.docx_path,
                kwargs={
                    'keep_layout': True,
                    'laparams': {
                        'line_overlap': 0.5,
                        'char_margin': 1.0,
                        'detect_vertical': True
                    },
                    'table_settings': {
                        'vertical_strategy': 'lines',
                        'horizontal_strategy': 'lines',
                        'intersection_tolerance': 5
                    }
                },
                progress_callback=self.update_progress
            )
            self.conversion_finished.emit(
                True,
                f"✅ 转换成功！\n\n"
                f"📄 原始文件: {os.path.basename(self.pdf_path)}\n"
                f"📝 输出文件: {os.path.basename(self.docx_path)}\n\n"
                f"✨ 转换质量:\n"
                f"• 表格结构保留完整\n"
                f"• 原始排版精确匹配\n"
                f"• 图片嵌入精度300dpi\n"
                f"• 支持复杂多栏排版"
            )
        except Exception as e:
            logging.error(f"转换失败: {str(e)}")
            self.conversion_finished.emit(False, f"❌ 转换失败: {str(e)}")

    def update_progress(self, pg, total):
        percent = int(pg/total*100)
        self.progress_updated.emit(percent, f"正在转换第 {pg}/{total} 页...")
        if self._cancel:
            raise Exception("用户取消转换")

    def cancel(self):
        self._cancel = True


class PDFConverterApp(QMainWindow):
    """主应用程序窗口"""

    def __init__(self):
        super().__init__()
        self.converter_thread = None
        self.setup_ui()
        logging.info("应用程序初始化完成")

    def setup_ui(self):
        """初始化UI界面"""
        self.setWindowTitle("PDF转Word专业工具")
        self.setMinimumSize(500, 400)
        self.setWindowIcon(QIcon.fromTheme("document-convert"))

        # 主窗口布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(20, 15, 20, 15)
        main_layout.setSpacing(15)

        # 添加界面组件
        self.setup_header(main_layout)
        self.setup_file_section(main_layout)
        self.setup_progress_section(main_layout)

        # 状态栏
        self.status_bar = self.statusBar()
        self.status_bar.setStyleSheet("""
            QStatusBar {
                background: #F5F7FA;
                color: #666;
                border-top: 1px solid #E0E3E8;
                padding-left: 10px;
                font-size: 11px;
            }
        """)

    def setup_header(self, layout):
        """设置标题区域"""
        header = QWidget()
        header_layout = QHBoxLayout(header)
        header_layout.setContentsMargins(0, 0, 0, 0)
        header_layout.setSpacing(15)

        # 图标
        icon_label = QLabel()
        icon_pixmap = QIcon.fromTheme("application-pdf").pixmap(40, 40)
        icon_label.setPixmap(icon_pixmap)

        # 标题文本
        title_box = QVBoxLayout()
        title_box.setSpacing(2)

        title_label = QLabel("PDF转Word工具")
        title_label.setStyleSheet("""
            QLabel {
                font-size: 18px;
                font-weight: bold;
                color: #2C3E50;
            }
        """)

        title_box.addWidget(title_label)

        header_layout.addWidget(icon_label)
        header_layout.addLayout(title_box)
        header_layout.addStretch()

        layout.addWidget(header)

        # 分隔线
        separator = QFrame()
        separator.setFrameShape(QFrame.HLine)
        separator.setFrameShadow(QFrame.Sunken)
        separator.setStyleSheet("border-color: #E0E3E8;")
        layout.addWidget(separator)

    def setup_file_section(self, layout):
        """设置文件选择区域"""
        file_group = QGroupBox("文件设置")
        file_group.setStyleSheet("""
            QGroupBox {
                border: 1px solid #E0E3E8;
                border-radius: 6px;
                margin-top: 10px;
                padding-top: 15px;
                font-size: 14px;
                color: #34495E;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                left: 10px;
            }
        """)

        file_layout = QVBoxLayout(file_group)
        file_layout.setSpacing(12)
        file_layout.setContentsMargins(12, 15, 12, 15)

        # PDF文件选择
        self.setup_pdf_selector(file_layout)

        # Word文件保存位置
        self.setup_output_selector(file_layout)

        layout.addWidget(file_group)

    def setup_pdf_selector(self, layout):
        """设置PDF选择器"""
        pdf_box = QWidget()
        pdf_layout = QHBoxLayout(pdf_box)
        pdf_layout.setContentsMargins(0, 0, 0, 0)
        pdf_layout.setSpacing(10)

        self.btn_select_pdf = QPushButton("📂 选择PDF")
        self.btn_select_pdf.setFixedWidth(120)
        self.btn_select_pdf.setStyleSheet(self.get_button_style("#3498DB"))
        self.btn_select_pdf.clicked.connect(self.select_pdf_file)

        self.pdf_path_label = QLabel("未选择文件")
        self.pdf_path_label.setStyleSheet(self.get_path_label_style())
        self.pdf_path_label.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Preferred)

        pdf_layout.addWidget(self.btn_select_pdf)
        pdf_layout.addWidget(self.pdf_path_label)
        layout.addWidget(pdf_box)

    def setup_output_selector(self, layout):
        """设置输出路径选择器"""
        word_box = QWidget()
        word_layout = QHBoxLayout(word_box)
        word_layout.setContentsMargins(0, 0, 0, 0)
        word_layout.setSpacing(10)

        self.btn_select_output = QPushButton("💾 设置保存路径")
        self.btn_select_output.setFixedWidth(120)
        self.btn_select_output.setStyleSheet(self.get_button_style("#2ECC71"))
        self.btn_select_output.clicked.connect(self.set_output_path)

        self.output_path_label = QLabel("未设置路径")
        self.output_path_label.setStyleSheet(self.get_path_label_style())
        self.output_path_label.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Preferred)

        word_layout.addWidget(self.btn_select_output)
        word_layout.addWidget(self.output_path_label)
        layout.addWidget(word_box)

    def setup_progress_section(self, layout):
        """设置进度显示区域"""
        progress_group = QGroupBox("转换进度")
        progress_group.setStyleSheet("""
            QGroupBox {
                border: 1px solid #E0E3E8;
                border-radius: 6px;
                margin-top: 10px;
                padding-top: 15px;
                font-size: 14px;
                color: #34495E;
            }
        """)

        progress_layout = QVBoxLayout(progress_group)
        progress_layout.setSpacing(15)
        progress_layout.setContentsMargins(12, 15, 12, 15)

        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        self.progress_bar.setTextVisible(False)
        self.progress_bar.setStyleSheet("""
            QProgressBar {
                height: 16px;
                border-radius: 8px;
                background: #ECF0F1;
            }
            QProgressBar::chunk {
                background: qlineargradient(
                    x1:0, y1:0, x2:1, y2:0,
                    stop:0 #3498DB, stop:1 #2ECC71);
                border-radius: 8px;
            }
        """)

        # 进度标签
        self.progress_label = QLabel("准备就绪")
        self.progress_label.setAlignment(Qt.AlignCenter)
        self.progress_label.setStyleSheet("""
            QLabel {
                font-size: 12px;
                color: #7F8C8D;
            }
        """)

        # 转换按钮
        self.btn_convert = QPushButton("开始转换")
        self.btn_convert.setMinimumHeight(36)
        self.btn_convert.setEnabled(False)
        self.btn_convert.setStyleSheet("""
            QPushButton {
                background: qlineargradient(
                    x1:0, y1:0, x2:1, y2:0,
                    stop:0 #3498DB, stop:1 #2ECC71);
                color: white;
                font-size: 14px;
                font-weight: bold;
                border-radius: 6px;
                padding: 8px;
            }
            QPushButton:hover {
                background: qlineargradient(
                    x1:0, y1:0, x2:1, y2:0,
                    stop:0 #2980B9, stop:1 #27AE60);
            }
            QPushButton:pressed {
                background: qlineargradient(
                    x1:0, y1:0, x2:1, y2:0,
                    stop:0 #2472A4, stop:1 #219653);
            }
            QPushButton:disabled {
                background: #BDC3C7;
                color: #7F8C8D;
            }
        """)
        self.btn_convert.clicked.connect(self.toggle_conversion)

        progress_layout.addWidget(self.progress_bar)
        progress_layout.addWidget(self.progress_label)
        progress_layout.addWidget(self.btn_convert)
        layout.addWidget(progress_group)

    def get_button_style(self, color):
        """获取按钮样式表"""
        return f"""
            QPushButton {{
                background: {color};
                color: white;
                font-weight: bold;
                border-radius: 5px;
                padding: 6px 10px;
                font-size: 12px;
            }}
            QPushButton:hover {{
                background: {self.darken_color(color, 10)};
            }}
            QPushButton:pressed {{
                background: {self.darken_color(color, 20)};
            }}
        """

    def get_path_label_style(self):
        """获取路径标签样式表"""
        return """
            QLabel {
                background: #F8F9FA;
                border: 1px dashed #BDC3C7;
                border-radius: 5px;
                padding: 8px 12px;
                color: #7F8C8D;
                font-size: 12px;
            }
        """

    def darken_color(self, hex_color, percent):
        """颜色变暗"""
        color = QColor(hex_color)
        return color.darker(100 + percent).name()

    def select_pdf_file(self):
        """选择PDF文件"""
        try:
            options = QFileDialog.Options()
            path, _ = QFileDialog.getOpenFileName(
                self,
                "选择PDF文件",
                os.path.expanduser("~"),
                "PDF文件 (*.pdf);;所有文件 (*)",
                options=options
            )

            if path:
                logging.info(f"已选择PDF文件: {path}")
                self.pdf_path_label.setText(path)
                self.auto_generate_output_path(path)
                self.progress_label.setText("已选择PDF文件，准备转换")
                self.btn_convert.setEnabled(True)

                # 自动设置输出路径
                if "未设置" in self.output_path_label.text():
                    self.auto_generate_output_path(path)
        except Exception as e:
            logging.error(f"选择PDF文件错误: {str(e)}")
            QMessageBox.critical(self, "错误", f"无法选择文件:\n{str(e)}")

    def set_output_path(self):
        """设置输出文件路径"""
        try:
            default_path = ""
            if "未设置" not in self.output_path_label.text():
                default_path = self.output_path_label.text()
            elif self.pdf_path_label.text() != "未选择文件":
                default_path = os.path.splitext(
                    self.pdf_path_label.text())[0] + ".docx"

            path, _ = QFileDialog.getSaveFileName(
                self,
                "保存Word文件",
                default_path,
                "Word文档 (*.docx)"
            )

            if path:
                if not path.endswith(".docx"):
                    path += ".docx"
                self.output_path_label.setText(path)
                self.progress_label.setText("输出路径已设置")
        except Exception as e:
            logging.error(f"设置输出路径错误: {str(e)}")
            QMessageBox.critical(self, "错误", f"无法设置输出路径:\n{str(e)}")

    def auto_generate_output_path(self, pdf_path):
        """自动生成输出路径"""
        try:
            base = os.path.splitext(pdf_path)[0]
            counter = 1
            output_path = f"{base}_converted.docx"

            while os.path.exists(output_path):
                output_path = f"{base}_converted_{counter}.docx"
                counter += 1

            self.output_path_label.setText(output_path)
        except Exception as e:
            logging.error(f"自动生成输出路径错误: {str(e)}")

    def toggle_conversion(self):
        """切换转换状态"""
        if self.converter_thread and self.converter_thread.isRunning():
            self.cancel_conversion()
        else:
            self.start_conversion()

    def start_conversion(self):
        """开始转换"""
        pdf_path = self.pdf_path_label.text()
        output_path = self.output_path_label.text()

        # 验证输入
        if not os.path.isfile(pdf_path):
            QMessageBox.warning(self, "警告", "请选择有效的PDF文件")
            return

        if not output_path.endswith(".docx"):
            QMessageBox.warning(self, "警告", "输出路径必须是.docx文件")
            return

        try:
            # 初始化转换线程
            self.converter_thread = PDFConverterThread(pdf_path, output_path)
            self.converter_thread.progress_updated.connect(
                self.update_progress)
            self.converter_thread.conversion_finished.connect(
                self.handle_conversion_result)
            self.converter_thread.start()

            # 更新UI状态
            self.btn_convert.setText("停止转换")
            self.btn_select_pdf.setEnabled(False)
            self.btn_select_output.setEnabled(False)
            self.progress_label.setText("正在初始化转换...")

        except Exception as e:
            logging.error(f"启动转换线程错误: {str(e)}")
            QMessageBox.critical(self, "错误", f"无法开始转换:\n{str(e)}")

    def cancel_conversion(self):
        """取消转换"""
        if self.converter_thread and self.converter_thread.isRunning():
            self.converter_thread.cancel()
            self.btn_convert.setEnabled(False)
            self.progress_label.setText("正在停止转换...")
            logging.info("用户请求取消转换")

    def update_progress(self, percent, message):
        """更新进度"""
        self.progress_bar.setValue(percent)
        self.progress_label.setText(message)
        self.status_bar.showMessage(f"进度: {percent}% - {message}")

    def handle_conversion_result(self, success, message):
        """处理转换结果"""
        # 重置UI状态
        self.btn_convert.setText("开始转换")
        self.btn_convert.setEnabled(True)
        self.btn_select_pdf.setEnabled(True)
        self.btn_select_output.setEnabled(True)

        if success:
            self.progress_bar.setValue(100)
            self.progress_label.setText("转换完成！")
            logging.info("PDF转换成功完成")

            # 显示成功消息
            msg_box = QMessageBox(self)
            msg_box.setWindowTitle("转换成功")
            msg_box.setIcon(QMessageBox.Information)
            msg_box.setText(message)
            msg_box.setStandardButtons(QMessageBox.Ok)
            msg_box.exec_()

            # 打开输出目录
            self.open_output_directory()
        else:
            self.progress_bar.setValue(0)
            self.progress_label.setText("转换失败")
            logging.error(f"转换失败: {message}")
            QMessageBox.critical(self, "错误", message)

    def open_output_directory(self):
        """打开输出目录"""
        output_path = self.output_path_label.text()
        if output_path and os.path.isfile(output_path):
            try:
                output_dir = os.path.dirname(output_path)
                if sys.platform == "win32":
                    os.startfile(output_dir)
                elif sys.platform == "darwin":
                    os.system(f'open "{output_dir}"')
                else:
                    os.system(f'xdg-open "{output_dir}"')
            except Exception as e:
                logging.error(f"打开输出目录错误: {str(e)}")

    def closeEvent(self, event):
        """关闭事件处理"""
        if self.converter_thread and self.converter_thread.isRunning():
            reply = QMessageBox.question(
                self,
                "确认退出",
                "转换正在进行中，确定要退出吗？",
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.No
            )

            if reply == QMessageBox.Yes:
                self.converter_thread.cancel()
                self.converter_thread.wait()
                event.accept()
            else:
                event.ignore()
        else:
            event.accept()


if __name__ == "__main__":
    # 创建应用实例
    app = QApplication(sys.argv)
    app.setStyle('Fusion')

    # 设置全局字体
    if sys.platform == 'win32':
        app.setFont(QFont("Microsoft YaHei", 9))
    elif sys.platform == 'darwin':
        app.setFont(QFont("PingFang SC", 12))
    else:
        app.setFont(QFont("Noto Sans CJK SC", 10))

    # 创建并显示主窗口
    window = PDFConverterApp()
    window.show()

    # 运行应用
    sys.exit(app.exec_())
